//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Globalization;
using System.Text;

namespace OpenLS.Spreadsheet
{
    class ComplexParser
    {
        public bool TryParse(string text, out Complex result)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                foreach (char c in text)
                {
                    switch (c)
                    {
                        case '+':
                        case '-':
                        case 'e':
                        case 'i':
                        case 'j':
                            sb.Append(c);
                            break;
                        default:
                            if (char.IsNumber(c)|| c == '.')
                                sb.Append(c);
                            break;
                    }
                }
                this.text = sb.ToString();
                double i = GetInverted();
                double num = GetNumber();
                char cc = CurrentChar();
                switch (cc)
                {
                    case 'i':
                    case 'j':
                        if (double.IsNaN(num))
                            num = 1;
                        num = i * num;
                        result = new Complex(0, num, cc);
                        return HasNoMoreData();
                    case '\0':
                        num = i * num;
                        result = new Complex(num, 0, 'i');
                        return HasNoMoreData();

                }
                num = num * i;
                i = GetInverted();
                double num2 = GetNumber();
                if (double.IsNaN(num2))
                    num2 = 1;
                num2 = i * num2;
                switch (CurrentChar())
                {
                    case 'i':
                        result = new Complex(num, num2, 'i');
                        return HasNoMoreData();
                    case 'j':
                        result = new Complex(num, num2, 'j');
                        return HasNoMoreData();

                }
            }
            catch (Exception)
            { }
            result = new Complex();
            return false;
        }

        private bool HasNoMoreData()
        {
            return position >= text.Length - 1;
        }
        string text;
        int position;
        int GetInverted()
        {
            switch (text[position])
            {
                case '+':
                    position++;
                    return 1;
                case '-':
                    position++;
                    return -1;
            }
            return 1;
        }
        double GetNumber()
        {
            StringBuilder sb = new StringBuilder();
            while (char.IsNumber(CurrentChar()) || CurrentChar() == '.') //\\
            {
                sb.Append(CurrentChar());
                position++;
            }
            if (sb.Length == 0)
                return double.NaN;
            return double.Parse(sb.ToString(), CultureInfo.InvariantCulture);
        }
        char CurrentChar()
        {
            if (position < text.Length)
            return text[position];
        return '\0';
        }
    }
}
